<template>
  <div class="containers bpm" style="margin-top: 0px">
    <div ref="canvas" class="canvas" />
    <property-panel
      class="property-panel"
      v-if="bpmnModeler"
      :modeler="bpmnModeler"
      :procDefKey="procDefKey"
      :formList="formList"
      @resetKey="resetKey"
    />
    <el-button-group class="toolbar">
      <el-tooltip
        class="item"
        effect="dark"
        content="下载流程图"
        placement="bottom"
      >
        <el-button type="mini" size="mini" @click="downloadSvg"
          ><i class="el-icon-download"
        /></el-button>
      </el-tooltip>
      <el-tooltip
        class="item"
        effect="dark"
        content="下载流程文件"
        placement="bottom"
      >
        <el-button type="mini" size="mini" @click="downloadBpmn"
          ><i class="el-icon-download"
        /></el-button>
      </el-tooltip>
      <el-tooltip class="item" effect="dark" content="撤销" placement="bottom">
        <el-button size="mini"
          ><i class="el-icon-refresh-left" @click="undo"
        /></el-button>
      </el-tooltip>
      <el-tooltip class="item" effect="dark" content="恢复" placement="bottom">
        <el-button size="mini"
          ><i
            class="el-icon-refresh-right"
            :class="!canRedo ? 'default-undo' : ''"
            @click="redo"
        /></el-button>
      </el-tooltip>
      <el-tooltip class="item" effect="dark" content="放大" placement="bottom">
        <el-button size="mini" @click="zoom(0.05)"
          ><i class="el-icon-zoom-in"
        /></el-button>
      </el-tooltip>
      <el-tooltip class="item" effect="dark" content="缩小" placement="bottom">
        <el-button size="mini" @click="zoom(-0.05)"
          ><i class="el-icon-zoom-out"
        /></el-button>
      </el-tooltip>
    </el-button-group>
  </div>
</template>

<script>
import BpmnModeler from "bpmn-js/lib/Modeler"; // bpmn-js 设计器
import activitiModdleDescriptor from "@/components/ExtBpmn/activiti.json";
import customTranslate from "@/components/ExtBpmn/customTranslate/customTranslate";
import customControlsModule from "@/components/ExtBpmn/customControls";
import BpmData from "@/components/ExtBpmn/BpmData";
import { saveXml, getXml } from "@/api/wf/process";
import PropertyPanel from "@/components/ExtBpmn/PropertyPanel";
import defaultDiagram from "@/components/ExtBpmn/defaultDiagram";

export default {
  components: {
    PropertyPanel,
  },
  props: {
    id: {
      type: String,
      default: null,
    },
    title: {
      type: String,
      default: null,
    },
    procDefKey: {
      type: String,
      default: null,
    },
  },
  data() {
    return {
      svgStr: null,
      bpmnModeler: null,
      element: null,
      bpmData: new BpmData(),
      scale: 1.0,
      canRedo: false,
      formList:{list:[]},//表单数据
    };
  },
  mounted() {
    const canvas = this.$refs.canvas;
    var customTranslateModule = {
      translate: ["value", customTranslate],
    };
    // 生成实例
    this.bpmnModeler = new BpmnModeler({
      container: canvas,
      // 添加翻译模块
      additionalModules: [customTranslateModule, customControlsModule],
      moddleExtensions: {
        activiti: activitiModdleDescriptor,
      },
    });

    this.createNewDiagram(defaultDiagram("Process_1"));
    this.adjustPalette();
  },
  methods: {
    resetKey(value) {
      this.$emit('resetKey', value)
    },
    //获取xml
    saveTempXml() {
      const _this = this;
      return new Promise(function (resolve) {
        _this.bpmnModeler.saveXML(function (err, xml) {
          if (err) {
            reject(err);
          }
          resolve(xml);
        });
      });
    },
    //获取svg
    saveTempSvg() {
      const _this = this;
      return new Promise(function (resolve) {
        _this.bpmnModeler.saveSVG((err, svg) => {
          if (err) {
            reject(err);
            return;
          }
          resolve(svg);
        });
      });
    },
    createNewDiagram(xml) {
      // 将字符串转换成图显示出来
      this.bpmnModeler.importXML(xml, (err) => {
        if (err) {
          this.bpmnModeler.importXML(defaultDiagram(this.procDefKey), (err) => {
            if (err) {
              console.log("create default diagram error", err);
            }
          });
        }
      });
    },
    // 调整左侧工具栏排版
    adjustPalette() {
      try {
        // 获取 bpmn 设计器实例
        const canvas = this.$refs.canvas;
        const djsPalette = canvas.children[0].children[1].children[4];
        const djsPalStyle = {
          width: "130px",
          padding: "5px",
          background: "white",
          left: "20px",
          borderRadius: 0,
        };
        for (var key in djsPalStyle) {
          djsPalette.style[key] = djsPalStyle[key];
        }
        const palette = djsPalette.children[0];
        const allGroups = palette.children;
        // 修改控件样式
        for (const allGroup of allGroups) {
          const group = allGroup;
          for (var cKey in group.children) {
            const control = group.children[cKey];
            const controlStyle = {
              display: "flex",
              justifyContent: "flex-start",
              alignItems: "center",
              width: "100%",
              padding: "5px",
            };
            if (
              control.className &&
              control.dataset &&
              control.className.indexOf("entry") !== -1
            ) {
              const controlProps = this.bpmData.getControl(
                control.dataset.action
              );
              if (!controlProps.title) {
                control.style["display"] = "none";
              } else {
                control.innerHTML = `<div style='font-size: 14px;font-weight:500;margin-left:15px;'>${controlProps["title"]}</div>`;
                for (var csKey in controlStyle) {
                  control.style[csKey] = controlStyle[csKey];
                }
              }
            }
          }
        }
      } catch (e) {
        console.log(e);
      }
    },
    downloadSvg() {
      const _this = this;
      this.bpmnModeler.saveSVG(function (err, svg) {
        if (err) {
          console.error(err);
          return;
        }
        const { filename, href } = _this.setEncoded("SVG", svg);
        if (href && filename) {
          const a = document.createElement("a");
          a.download = filename;
          a.href = href;
          a.click();
          URL.revokeObjectURL(a.href);
        }
      });
    },
    downloadBpmn() {
      const _this = this;
      this.bpmnModeler.saveXML(function (err, xml) {
        if (err) {
          console.error(err);
          return;
        }
        const { filename, href } = _this.setEncoded("BPMN", xml);
        if (href && filename) {
          const a = document.createElement("a");
          a.download = filename; // 指定下载的文件名
          a.href = href; //  URL对象
          a.click(); // 模拟点击
          URL.revokeObjectURL(a.href); // 释放URL 对象
        }
      });
    },
    setEncoded(type, data) {
      const encodedData = encodeURIComponent(data);
      if (data) {
        if (type === "BPMN") {
          return {
            filename: "diagram.bpmn",
            href: "data:application/bpmn20-xml;charset=UTF-8," + encodedData,
            data: data,
          };
        }
        if (type === "SVG") {
          return {
            filename: "diagram.svg",
            href: "data:application/text/xml;charset=UTF-8," + encodedData,
            data: data,
          };
        }
      }
    },
    undo() {
      this.bpmnModeler.get("commandStack").undo();
      this.canRedo = this.bpmnModeler.get("commandStack").canRedo();
    },
    redo() {
      if (!this.canRedo) {
        return;
      }
      this.bpmnModeler.get("commandStack").redo();
      this.canRedo = this.bpmnModeler.get("commandStack").canRedo();
    },
    zoom(val) {
      const newScale = !val
        ? 1.0
        : this.scale + val <= 0.2
        ? 0.2
        : this.scale + val;
      this.bpmnModeler.get("canvas").zoom(newScale);
      this.scale = newScale;
    },
  },
};
</script>

<style lang='scss'>
/*左边工具栏以及编辑节点的样式*/
@import "~bpmn-js/dist/assets/diagram-js.css";
@import "~bpmn-js/dist/assets/bpmn-font/css/bpmn.css";
@import "~bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css";
@import "~bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css";
</style>
<style lang="scss" scoped>
.property-panel {
  position: absolute;
  right: 0px;
  top: 0px;
  border-left: 1px solid #cccccc;
  width: 300px;
  height: 100%;
}

.bpm {
  margin-left: 60px;
  width: 95%;
}
</style>
